package com.wubai.ranger.api;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.deploy.net.URLEncoder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;

public class RangerAudit {

    // 审计日志实体类
    public static class AuditLog {
        @JsonProperty("reqUser") private String user;
        @JsonProperty("resource") private String resource;
        @JsonProperty("evtTime") private Date eventTime;
        @JsonProperty("accessResult") private String result;
        // 其他字段根据需要添加

        // Getters
        public String getUser() { return user; }
        public String getResource() { return resource; }
        public Date getEventTime() { return eventTime; }
        public String getResult() { return result; }
    }

    // Ranger客户端实现
    public static class RangerAuditClient {
        private static final String AUDIT_API_PATH = "/service/plugins/audits";
        private final String baseUrl;
        private final CloseableHttpClient httpClient;
        private final ObjectMapper mapper = new ObjectMapper();

        public RangerAuditClient(String serverUrl) {
            this.baseUrl = serverUrl + AUDIT_API_PATH;
            this.httpClient = HttpClients.createDefault();
        }

        public List<AuditLog> queryAccessLogs(String user, String table, Date start, Date end) throws IOException {
            List<AuditLog> allLogs = new ArrayList<>();
            int currentPage = 0;
            boolean hasMore = true;

            while (hasMore) {
                String url = String.format("%s?user=%s&resource=%s&startTime=%s&endTime=%s&pageSize=100&pageNo=%d",
                        baseUrl, user, URLEncoder.encode("" + table, String.valueOf(StandardCharsets.UTF_8)),
                        Instant.ofEpochMilli(start.getTime()).toString(),
                        Instant.ofEpochMilli(end.getTime()).toString(),
                        currentPage++);

                HttpGet request = new HttpGet(url);
                request.addHeader("Authorization", "Bearer " + ApiKeyHolder.API_KEY);

                try (CloseableHttpResponse response = httpClient.execute(request)) {
                    String json = EntityUtils.toString(response.getEntity());
                    AuditResponse resp = mapper.readValue(json, AuditResponse.class);

                    allLogs.addAll(resp.getLogs());
                    hasMore = resp.getLogs().size() >= 100;
                }
            }
            return allLogs;
        }

        // 响应结构
        private static class AuditResponse {
            @JsonProperty("auditList") private List<AuditLog> logs;
            List<AuditLog> getLogs() { return logs; }
        }
    }

    // API密钥管理
    private static class ApiKeyHolder {
        public static final String API_KEY = "rangeradmin:Huawei12#$@1234";
    }

    public static void main(String[] args) {
        try {
            RangerAuditClient client = new RangerAuditClient("https://10.203.13.253:21405");

            // 设置查询时间范围（示例：过去一个月）
            Date endDate = new Date();
            Date startDate = Date.from(Instant.now().minus(30, ChronoUnit.DAYS));

            List<AuditLog> logs = client.queryAccessLogs(
                    "sharkdw",
                    "sharkdwm",
                    startDate,
                    endDate
            );

            // 统计允许访问次数
            long accessCount = logs.stream()
                    .filter(log -> "ALLOW".equals(log.getResult()))
                    .count();

            System.out.printf("用户 sharkdw 在指定时间段内访问 table1 的次数为：%d 次%n", accessCount);

        } catch (IOException e) {
            System.err.println("审计查询失败：" + e.getMessage());
            e.printStackTrace();
        }
    }
}
